/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#ifndef __PlayPenTests_H__
#define __PlayPenTests_H__

#include "VisualTest.h"
#include "SamplePlugin.h"
#include "SdkSample.h"

using namespace Ogre;

#ifdef OGRE_BUILD_COMPONENT_MESHLODGENERATOR
//---------------------------------------------------------------------------
/** Test of manual LOD */
class _OgreSampleClassExport PlayPen_ManualLOD : public VisualTest
{
public:

    PlayPen_ManualLOD();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    String getLODMesh();

    AnimationState* mAnimation;

};

//---------------------------------------------------------------------------
/** Test of Manual LOD from a file */
class _OgreSampleClassExport PlayPen_ManualLODFromFile : public PlayPen_ManualLOD
{
public:

    PlayPen_ManualLODFromFile();

protected:

    String getLODMesh();

};
#endif
//---------------------------------------------------------------------------
/** Test of Manual Blending */
class _OgreSampleClassExport PlayPen_ManualBlend : public VisualTest
{
public:

    PlayPen_ManualBlend();

protected:

    void setupContent() override;

};

//---------------------------------------------------------------------------
/** Testing sphere projection */
class _OgreSampleClassExport PlayPen_ProjectSphere : public VisualTest
{
public:

    PlayPen_ProjectSphere();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    Sphere* mProjectionSphere;
    ManualObject* mScissorRect;
    void setupContent() override;

};

//---------------------------------------------------------------------------
/** Testing setting the camera's direction */
class _OgreSampleClassExport PlayPen_CameraSetDirection : public VisualTest
{
public:

    PlayPen_CameraSetDirection();
    void buttonHit(OgreBites::Button* button) override;
    void checkBoxToggled(OgreBites::CheckBox* box) override;

protected:

    bool mUseParentNode;
    bool mUseFixedYaw;
    SceneNode* mParentNode;
    Vector3 mFocus;
    void setupContent() override;
    void toggleParentNode();
    void toggleFixedYaw();
    void track();

};

//---------------------------------------------------------------------------
/** Testing morph animation with normals */
class _OgreSampleClassExport PlayPen_MorphAnimationWithNormals : public VisualTest
{
public:

    PlayPen_MorphAnimationWithNormals();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    AnimationState* mAnimations[2];

};

//---------------------------------------------------------------------------
/** Testing morph animation without normals */
class _OgreSampleClassExport PlayPen_MorphAnimationWithoutNormals : public VisualTest
{
public:

    PlayPen_MorphAnimationWithoutNormals();
    bool frameStarted(const FrameEvent& evt) override;
    
protected:

    void setupContent() override;
    AnimationState* mAnimations[2];

};

//---------------------------------------------------------------------------
/** Testing pose animation with normals */
class _OgreSampleClassExport PlayPen_PoseAnimationWithNormals : public VisualTest
{
public:

    PlayPen_PoseAnimationWithNormals();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    AnimationState* mAnimations[2];

};

//---------------------------------------------------------------------------
/** Testing pose animation without normals */
class _OgreSampleClassExport PlayPen_PoseAnimationWithoutNormals : public VisualTest
{
public:

    PlayPen_PoseAnimationWithoutNormals();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    AnimationState* mAnimations[2];

};
//
//---------------------------------------------------------------------------
/** Testing scene node tracking */
class _OgreSampleClassExport PlayPen_SceneNodeTracking : public VisualTest
{
public:

    PlayPen_SceneNodeTracking();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    AnimationState* mAnimState;

};
//---------------------------------------------------------------------------

// forward declare, but don't define yet to keep this header clean
class StencilOpQueueListener;

/** Testing stencil glow effects */
class _OgreSampleClassExport PlayPen_StencilGlow : public VisualTest
{
public:

    PlayPen_StencilGlow();
    virtual ~PlayPen_StencilGlow();

protected:

    void setupContent() override;
    StencilOpQueueListener* mStencilListener;

};
//------------------------------------------------------------------------------
/** Tests normal mapping with mirrored UVs */
class _OgreSampleClassExport PlayPen_NormalMapMirroredUVs : public VisualTest
{
public:

    PlayPen_NormalMapMirroredUVs();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests mipmaps on a transparent material */
class _OgreSampleClassExport PlayPen_TransparencyMipMaps : public VisualTest
{
public:

    PlayPen_TransparencyMipMaps();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests basic plane object rendering */
class _OgreSampleClassExport PlayPen_BasicPlane : public VisualTest
{
public:

    PlayPen_BasicPlane();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests BSP plugin */
class _OgreSampleClassExport PlayPen_Bsp : public VisualTest
{
public:

    PlayPen_Bsp();

    StringVector getRequiredPlugins() override
    {
        StringVector names;
        names.push_back("BSP Scene Manager");
        return names;
    }

    void createSceneManager() override
    {
        mSceneMgr = mRoot->createSceneManager("BspSceneManager");
#ifdef OGRE_BUILD_COMPONENT_RTSHADERSYSTEM
        mShaderGenerator->addSceneManager(mSceneMgr);
#endif
    }

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests simple projection */
class _OgreSampleClassExport PlayPen_Projection : public VisualTest
{
public:

    PlayPen_Projection();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests multiple viewports */
class _OgreSampleClassExport PlayPen_MultiViewports : public VisualTest
{
public:

    PlayPen_MultiViewports();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------

class RefractionTextureListener;
class ReflectionTextureListener;

/** Tests reflection/refraction. */
class _OgreSampleClassExport PlayPen_Distortion : public VisualTest
{
public:

    PlayPen_Distortion();
    virtual ~PlayPen_Distortion();

protected:

    void setupContent() override;
    void cleanupContent() override;

    RefractionTextureListener* mRefractionListener;
    ReflectionTextureListener* mReflectionListener;

};

//------------------------------------------------------------------------------
/** Tests skeletal animation */
class _OgreSampleClassExport PlayPen_SkeletalAnimation : public VisualTest
{
public:

    PlayPen_SkeletalAnimation();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests windowed viewports */
class _OgreSampleClassExport PlayPen_WindowedViewportMode : public VisualTest
{
public:

    PlayPen_WindowedViewportMode();

protected:

    void setupContent() override;

    void unloadResources() override;

};

//------------------------------------------------------------------------------
/** Tests visibility settings for sub entities */
class _OgreSampleClassExport PlayPen_SubEntityVisibility : public VisualTest
{
public:

    PlayPen_SubEntityVisibility();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests attaching objects to bones */
class _OgreSampleClassExport PlayPen_AttachObjectsToBones : public VisualTest
{
public:

    PlayPen_AttachObjectsToBones();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests orthographic rendering */
class _OgreSampleClassExport PlayPen_Ortho : public VisualTest
{
public:

    PlayPen_Ortho();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests clearing a running scene */
class _OgreSampleClassExport PlayPen_ClearScene : public VisualTest
{
public:

    PlayPen_ClearScene();
    bool isScreenshotFrame(int frame) override;

protected:
    void setupContent() override;
};

//------------------------------------------------------------------------------
/** Tests stencil shadows */
class _OgreSampleClassExport PlayPen_StencilShadows : public VisualTest
{
public:

    PlayPen_StencilShadows();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests stencil shadows with mixed operation submeshes */
class _OgreSampleClassExport PlayPen_StencilShadowsMixedOpSubMeshes : public VisualTest
{
public:

    PlayPen_StencilShadowsMixedOpSubMeshes();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests 2 spotlights casting light on a single mesh */
class _OgreSampleClassExport PlayPen_2Spotlights : public VisualTest
{
public:

    PlayPen_2Spotlights();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests texture shadows */
class _OgreSampleClassExport PlayPen_TextureShadows : public VisualTest
{
public:

    PlayPen_TextureShadows();

protected:

    void setupContent() override;
    void cleanupContent() override;

};

//------------------------------------------------------------------------------
/** Tests custom texture shadow caster materials */
class _OgreSampleClassExport PlayPen_TextureShadowsCustomCasterMat : public PlayPen_TextureShadows
{
public:

    PlayPen_TextureShadowsCustomCasterMat();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests a custom shadow receiver material for texture shadows */
class _OgreSampleClassExport PlayPen_TextureShadowsCustomReceiverMat : public PlayPen_TextureShadows
{
public:

    PlayPen_TextureShadowsCustomReceiverMat();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests applying a compositor to texture shadow rendering */
class _OgreSampleClassExport PlayPen_CompositorTextureShadows : public VisualTest
{
public:

    PlayPen_CompositorTextureShadows();

protected:

    void setupContent() override;
    void cleanupContent() override;

};

//------------------------------------------------------------------------------
/** Tests switching compositor techniques rapidly */
class _OgreSampleClassExport PlayPen_CompositorTechniqueSwitch : public VisualTest
{
public:

    PlayPen_CompositorTechniqueSwitch();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    void cleanupContent() override;

    CompositorInstance* mCompositorToSwitch;
    size_t mCompositorIndex;
    Real mTimeUntilNextToggle;
    StringVector mCompositorSchemeList;

};

//------------------------------------------------------------------------------
/** Tests creation and rendering of a whole lot of entities */
class _OgreSampleClassExport PlayPen_LotsAndLotsOfEntities : public VisualTest
{
public:

    PlayPen_LotsAndLotsOfEntities();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests infinite bounding boxes */
class _OgreSampleClassExport PlayPen_InfiniteAAB : public VisualTest
{
public:

    PlayPen_InfiniteAAB();

    StringVector getRequiredPlugins() override
    {
        StringVector names;
        names.push_back("BSP Scene Manager");
        return names;
    }

    void createSceneManager() override
    {
        mSceneMgr = mRoot->createSceneManager("BspSceneManager");
#ifdef OGRE_BUILD_COMPONENT_RTSHADERSYSTEM
        mShaderGenerator->addSceneManager(mSceneMgr);
#endif
    }

protected:

    void setupContent() override;
    void cleanupContent() override;

};

//------------------------------------------------------------------------------
/** Tests static geometry */
class _OgreSampleClassExport PlayPen_StaticGeometry : public VisualTest
{
public:

    PlayPen_StaticGeometry();

protected:

    void setupContent() override;

};

#ifdef OGRE_BUILD_COMPONENT_MESHLODGENERATOR
//------------------------------------------------------------------------------
/** Tests static geometry with LODs */
class _OgreSampleClassExport PlayPen_StaticGeometryWithLOD : public VisualTest
{
public:

    PlayPen_StaticGeometryWithLOD();

protected:

    void setupContent() override;

};
#endif

//------------------------------------------------------------------------------
/** Tests reloading resources */
class _OgreSampleClassExport PlayPen_ReloadResources : public VisualTest
{
public:

    PlayPen_ReloadResources();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    Real mReloadTimer;

};

//------------------------------------------------------------------------------
/** Tests particles with an RTT reflection */
class _OgreSampleClassExport PlayPen_ReflectedBillboards : public VisualTest
{
public:

    PlayPen_ReflectedBillboards();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests non-indexed manual object */
class _OgreSampleClassExport PlayPen_ManualObjectNonIndexed : public VisualTest
{
public:

    PlayPen_ManualObjectNonIndexed();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests non-indexed manual objects updated with fewer verts/faces */
class _OgreSampleClassExport PlayPen_ManualObjectNonIndexedUpdateSmaller : public PlayPen_ManualObjectNonIndexed
{
public:

    PlayPen_ManualObjectNonIndexedUpdateSmaller();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests non-indexed manual objects updated with more verts/faces */
class _OgreSampleClassExport PlayPen_ManualObjectNonIndexedUpdateLarger : public PlayPen_ManualObjectNonIndexed
{
public:

    PlayPen_ManualObjectNonIndexedUpdateLarger();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests indexed manual objects */
class _OgreSampleClassExport PlayPen_ManualObjectIndexed : public VisualTest
{
public:

    PlayPen_ManualObjectIndexed();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests indexed manual objects updating with less verts/faces */
class _OgreSampleClassExport PlayPen_ManualObjectIndexedUpdateSmaller : public PlayPen_ManualObjectIndexed
{
public:

    PlayPen_ManualObjectIndexedUpdateSmaller();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests indexed manual objects updating with more verts/faces */
class _OgreSampleClassExport PlayPen_ManualObjectIndexedUpdateLarger : public PlayPen_ManualObjectIndexed
{
public:

    PlayPen_ManualObjectIndexedUpdateLarger();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests billboard chain rendering */
class _OgreSampleClassExport PlayPen_BillboardChain : public VisualTest
{
public:

    PlayPen_BillboardChain();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests DDS cubemaps */
class _OgreSampleClassExport PlayPen_CubeDDS : public VisualTest
{
public:

    PlayPen_CubeDDS();

protected:

    void setupContent() override;

};

class _OgreSampleClassExport PlayPen_AlphaTex : public VisualTest
{
public:

    PlayPen_AlphaTex();

protected:

    void setupContent() override;

};

class PlayPen_TwoSidedLighting : public VisualTest
{
public:

    PlayPen_TwoSidedLighting();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests DXT1 loading */
class _OgreSampleClassExport PlayPen_Dxt1 : public VisualTest
{
public:

    PlayPen_Dxt1();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests DXT1 loading from memory */
class _OgreSampleClassExport PlayPen_Dxt1FromMemory : public VisualTest
{
public:

    PlayPen_Dxt1FromMemory();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests DXT1 loading with alpha channel */
class _OgreSampleClassExport PlayPen_Dxt1Alpha : public VisualTest
{
public:

    PlayPen_Dxt1Alpha();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests DXT3 loading */
class _OgreSampleClassExport PlayPen_Dxt3 : public VisualTest
{
public:

    PlayPen_Dxt3();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests DXT3 loading from memory */
class _OgreSampleClassExport PlayPen_Dxt3FromMemory : public VisualTest
{
public:

    PlayPen_Dxt3FromMemory();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests DXT5 loading */
class _OgreSampleClassExport PlayPen_Dxt5 : public VisualTest
{
public:

    PlayPen_Dxt5();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests ribbon trail rendering */
class _OgreSampleClassExport PlayPen_RibbonTrail : public VisualTest
{
public:

    PlayPen_RibbonTrail();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests diffuse blending */
class _OgreSampleClassExport PlayPen_BlendDiffuseColour : public VisualTest
{
public:

    PlayPen_BlendDiffuseColour();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests custom projection matrices */
class _OgreSampleClassExport PlayPen_CustomProjectionMatrix : public PlayPen_LotsAndLotsOfEntities
{
public:

    PlayPen_CustomProjectionMatrix();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests point sprites */
class _OgreSampleClassExport PlayPen_PointSprites : public VisualTest
{
public:

    PlayPen_PointSprites();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests excluding shadows from a viewport */
class _OgreSampleClassExport PlayPen_ViewportNoShadows : public VisualTest
{
public:

    PlayPen_ViewportNoShadows();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests serializing vertex colors in meshes */
class _OgreSampleClassExport PlayPen_SerialisedColour : public VisualTest
{
public:

    PlayPen_SerialisedColour();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests billboard facing */
class _OgreSampleClassExport PlayPen_BillboardAccurateFacing : public VisualTest
{
public:

    PlayPen_BillboardAccurateFacing();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests multiple scene managers */
class _OgreSampleClassExport PlayPen_MultiSceneManagersSimple : public VisualTest
{
public:

    PlayPen_MultiSceneManagersSimple();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests manually moving bones */
class _OgreSampleClassExport PlayPen_ManualBoneMovement : public VisualTest
{
public:

    PlayPen_ManualBoneMovement();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    Bone* mBone;

};

//------------------------------------------------------------------------------
/** Tests material schemes in viewports */
class _OgreSampleClassExport PlayPen_MaterialSchemes : public VisualTest
{
public:

    PlayPen_MaterialSchemes();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests material scehemes with listener */
class _OgreSampleClassExport PlayPen_MaterialSchemesListener : public VisualTest
{
public:

    PlayPen_MaterialSchemesListener();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests material schemes with LODs */
class _OgreSampleClassExport PlayPen_MaterialSchemesWithLOD : public VisualTest
{
public:

    PlayPen_MaterialSchemesWithLOD();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests material schemes in viewports with different LODs */
class _OgreSampleClassExport PlayPen_MaterialSchemesWithMismatchedLOD : public VisualTest
{
public:

    PlayPen_MaterialSchemesWithMismatchedLOD();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests hardware/software animation */
class _OgreSampleClassExport PlayPen_SkeletonAnimationOptimise : public VisualTest
{
public:

    PlayPen_SkeletonAnimationOptimise();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests vertex textures (DX only) */
class _OgreSampleClassExport PlayPen_VertexTexture : public VisualTest
{
public:

    PlayPen_VertexTexture();

    void testCapabilities(const RenderSystemCapabilities* caps) override
    {
        if(!caps->isShaderProfileSupported("hlsl") && !caps->isShaderProfileSupported("glsl"))
            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "not implemented");
    }

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests setting billboard origin */
class _OgreSampleClassExport PlayPen_BillboardOrigins : public VisualTest
{
public:

    PlayPen_BillboardOrigins();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests depth biasing */
class _OgreSampleClassExport PlayPen_DepthBias : public VisualTest
{
public:

    PlayPen_DepthBias();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests transparent texture shadow casters */
class _OgreSampleClassExport PlayPen_TextureShadowsTransparentCaster : public VisualTest
{
public:

    PlayPen_TextureShadowsTransparentCaster();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests integrated texture shadows */
class _OgreSampleClassExport PlayPen_TextureShadowsIntegrated : public VisualTest
{
public:

    PlayPen_TextureShadowsIntegrated();

protected:

    void setupContent() override;
    void cleanupContent() override;

};

//------------------------------------------------------------------------------
/** Tests integrated texture shadows with parallel splits */
class _OgreSampleClassExport PlayPen_TextureShadowsIntegratedPSSM : public VisualTest
{
public:

    PlayPen_TextureShadowsIntegratedPSSM();

protected:

    void setupContent() override;
    void cleanupContent() override;

};

//------------------------------------------------------------------------------
/** Tests light scissoring */
class _OgreSampleClassExport PlayPen_LightScissoring : public VisualTest
{
public:

    PlayPen_LightScissoring();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests light clipping planes */
class _OgreSampleClassExport PlayPen_LightClipPlanes : public VisualTest
{
public:

    PlayPen_LightClipPlanes();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests light clipping planes with lots of lights */
class _OgreSampleClassExport PlayPen_LightClipPlanesMoreLights : public VisualTest
{
public:

    PlayPen_LightClipPlanesMoreLights();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests MRT */
class _OgreSampleClassExport PlayPen_MRT : public VisualTest
{
public:

    PlayPen_MRT();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests applying many textures to a single material */
class _OgreSampleClassExport PlayPen_16Textures : public VisualTest
{
public:

    PlayPen_16Textures();
    void testCapabilities(const Ogre::RenderSystemCapabilities* caps) override;

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests view projections for spotlight shadow cameras */
class _OgreSampleClassExport PlayPen_SpotlightViewProj : public VisualTest
{
public:

    PlayPen_SpotlightViewProj();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests manual illumination stages */
class _OgreSampleClassExport PlayPen_ManualIlluminationStage : public VisualTest
{
public:

    PlayPen_ManualIlluminationStage();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests altering a mesh mid-simulation */
class _OgreSampleClassExport PlayPen_ReinitialiseEntityAlteredMesh : public VisualTest
{
public:

    PlayPen_ReinitialiseEntityAlteredMesh();
    bool frameStarted(const FrameEvent& evt) override;

protected:

    void setupContent() override;
    
    Mesh* mUpdate;
    Real mTimer;

};

//------------------------------------------------------------------------------
/** Tests sRGB textures */
class _OgreSampleClassExport PlayPen_SRGBtexture : public VisualTest
{
public:

    PlayPen_SRGBtexture();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests negative scaling */
class _OgreSampleClassExport PlayPen_NegativeScale : public VisualTest
{
public:

    PlayPen_NegativeScale();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests 2d manual object */
class _OgreSampleClassExport PlayPen_ManualObject2D : public VisualTest
{
public:

    PlayPen_ManualObject2D();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests shadow LODs */
class _OgreSampleClassExport PlayPen_ShadowLod : public VisualTest
{
public:

    PlayPen_ShadowLod();

protected:

    void setupContent() override;
    void cleanupContent() override;

};

//------------------------------------------------------------------------------
/** Tests rendering far from the origin */
class _OgreSampleClassExport PlayPen_FarFromOrigin : public VisualTest
{
public:

    PlayPen_FarFromOrigin();

protected:

    void setupContent() override;
    void cleanupContent() override;

};

//------------------------------------------------------------------------------
/** Tests geometry shaders */
class _OgreSampleClassExport PlayPen_GeometryShaders : public VisualTest
{
public:

    PlayPen_GeometryShaders();
    void testCapabilities(const Ogre::RenderSystemCapabilities* caps) override;

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests alpha to coverage support */
class _OgreSampleClassExport PlayPen_AlphaToCoverage : public VisualTest
{
public:

    PlayPen_AlphaToCoverage();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests light space shadow mapping (LiSPSM) shadow camera setup */
class _OgreSampleClassExport PlayPen_LiSPSM : public VisualTest
{
public:

    PlayPen_LiSPSM();

protected:

    void setupContent() override;
    void cleanupContent() override;

};

//------------------------------------------------------------------------------
/** Tests blitting one texture onto another */
class _OgreSampleClassExport PlayPen_BlitSubTextures : public VisualTest
{
public:

    PlayPen_BlitSubTextures();

protected:

    void setupContent() override;

};
//------------------------------------------------------------------------------
/** Tests blitting to texture with hardware scaling */
class _OgreSampleClassExport PlayPen_HardwareScaleBlit : public VisualTest
{
public:

    PlayPen_HardwareScaleBlit();

protected:

    void setupContent() override;

};
//------------------------------------------------------------------------------
/** Tests depth shadow mapping */
class _OgreSampleClassExport PlayPen_DepthShadowMap : public VisualTest
{
public:

    PlayPen_DepthShadowMap();

protected:
    std::unique_ptr<MovablePlane> movablePlane;
    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests non-unique resource names in different resource groups */
class _OgreSampleClassExport PlayPen_NonUniqueResourceNames : public VisualTest
{
public:

    PlayPen_NonUniqueResourceNames();

protected:

    void setupContent() override;
    void createMeshEntity(const String& group, Vector3 pos);

};
//------------------------------------------------------------------------------
/** Tests non-unique resource names in different resource groups */
class _OgreSampleClassExport PlayPen_BuildTangentOnAnimatedMesh : public VisualTest
{
public:

    PlayPen_BuildTangentOnAnimatedMesh();

protected:

    void setupContent() override;

};
//------------------------------------------------------------------------------
/** Tests 64 bit float DDS */
class _OgreSampleClassExport PlayPen_Float64DDS : public VisualTest
{
public:

    PlayPen_Float64DDS();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests 128bit float DDS */
class _OgreSampleClassExport PlayPen_Float128DDS : public VisualTest
{
public:

    PlayPen_Float128DDS();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests 16bit float DDS */
class _OgreSampleClassExport PlayPen_Float16DDS : public VisualTest
{
public:

    PlayPen_Float16DDS();

protected:

    void setupContent() override;

};

//------------------------------------------------------------------------------
/** Tests 32bit float DDS */
class _OgreSampleClassExport PlayPen_Float32DDS : public VisualTest
{
public:

    PlayPen_Float32DDS();

protected:

    void setupContent() override;

};

class _OgreSampleClassExport PlayPen_BillboardText : public VisualTest
{
public:
    PlayPen_BillboardText();

protected:
    void setupContent() override;
};

class _OgreSampleClassExport PlayPen_PBR : public OgreBites::SdkSample
{
public:
    PlayPen_PBR();

protected:
    void setupContent() override;
    void unloadResources() override;
};
//------------------------------------------------------------------------------

// some common tasks for these tests:
void addTextureDebugOverlay(const Ogre::String& texname, size_t i);
void addTextureDebugOverlay(const Ogre::TexturePtr& tex, size_t i);
void addTextureShadowDebugOverlay(size_t num, Ogre::SceneManager* mgr);
void clearDebugTextureOverlays();

#endif
